# Copyright 2005 Nigel Sim <nigel.sim@gmail.com>
# dmm and gDMM are used to capture data from rs232 enabled digital multi
# meters
#
# dmm is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# dmm is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with dmm; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


import serial

class QM1538:
	def __init__(self):
		self.s = serial.Serial('/dev/tts/USB0', baudrate=2400)

	def read(self):
		self.A = {}
		self.B = {}
		self.C = {}
		self.D = {}
		self.P = {}
		self.units = None
		self.quantity = None
		self.hold = False
		self.beep = False
		self.battery = False
		self.sign = False

		started = False
		finished = False
		while not finished:
			x = ord(self.s.read())
			seg = (x & 0xf0) >> 4
			val = x & 0x0f
			if not started:
				if seg == 1:
					started = True
			if started:
				if seg == 1:
					pass
				elif seg == 2:
					self.A[1] = (val & 0x1) > 0
					self.A[5] = (val & 0x4) > 0
					self.A[6] = (val & 0x2) > 0 
					self.sign = (val & 0x8) > 0
				elif seg == 3:
					self.A[2] = (val & 0x1) > 0
					self.A[7] = (val & 0x2) > 0
					self.A[3] = (val & 0x4) > 0
					self.A[4] = (val & 0x8) > 0
				elif seg == 4:
					self.B[1] = (val & 0x1) > 0
					self.B[6] = (val & 0x2) > 0
					self.B[5] = (val & 0x4) > 0
					self.P[1] = (val & 0x8) > 0
				elif seg == 5:
					self.B[2] = (val & 0x1) > 0
					self.B[7] = (val & 0x2) > 0
					self.B[3] = (val & 0x4) > 0
					self.B[4] = (val & 0x8) > 0
				elif seg == 6:
					self.C[1] = (val & 0x1) > 0
					self.C[6] = (val & 0x2) > 0
					self.C[5] = (val & 0x4) > 0
					self.P[2] = (val & 0x8) > 0
				elif seg == 7:
					self.C[2] = (val & 0x1) > 0
					self.C[7] = (val & 0x2) > 0
					self.C[3] = (val & 0x4) > 0
					self.C[4] = (val & 0x8) > 0
				elif seg == 8:
					self.D[1] = (val & 0x1) > 0
					self.D[6] = (val & 0x2) > 0
					self.D[5] = (val & 0x4) > 0
					self.P[3] = (val & 0x8) > 0
				elif seg == 9:
					self.D[2] = (val & 0x1) > 0
					self.D[7] = (val & 0x2) > 0
					self.D[3] = (val & 0x4) > 0
					self.D[4] = (val & 0x8) > 0
				elif seg == 10:
					if (val & 0x1) > 0:
						self.quantity = "Diode"
					if (val & 0x2) > 0:
						self.units = "k"
					if (val&0x4) > 0:
						self.units = "n"
					if (val&0x8) > 0:
						self.units = "u"
				elif seg == 11:
					self.beep = (val & 0x1) > 0
					if (val & 0x2) > 0:
						self.units = "M"
					if (val & 0x8) > 0:
						self.units = "m"
				elif seg == 12:
					if (val & 0x1) > 0:
						self.hold = True
					if (val & 0x2) > 0:
						self.quantity = "Delta"
					if (val&0x4) > 0:
						self.quantity = "Ohms"
					if (val&0x8) > 0:
						self.quantity = "F"
				elif seg == 13:
					if (val & 0x1) > 0:
						self.battery = True
					if (val & 0x2) > 0:
						self.quantity = "Hz"
					if (val&0x4) > 0:
						self.quantity = "V"
					if (val&0x8) > 0:
						self.quantity = "A"
				elif seg == 14:
					if (val & 0x1) > 0:
						pass
					if (val & 0x2) > 0:
						pass
					if (val&0x4) > 0:
						self.quantity = "deg C"
					if (val&0x8) > 0:
						pass
					finished = True
	def setToDigit(self, set):
		"""
		Converts a set of keys 1-7 into the digit it represents
		"""
		if not set[1] and set[2] and set[3] and not set[4] and not set[5] and not set[6] and not set[7]:
			return 1
		elif set[1] and set[2] and not set[3] and set[4] and set[5] and not set[6] and set[7]:
			return 2
		elif set[1] and set[2] and set[3] and set[4] and not set[5] and not set[6] and set[7]:
			return 3
		elif not set[1] and set[2] and set[3] and not set[4] and not set[5] and set[6] and set[7]:
			return 4
		elif set[1] and not set[2] and set[3] and set[4] and not set[5] and set[6] and set[7]:
			return 5
		elif set[1] and not set[2] and set[3] and set[4] and set[5] and set[6] and set[7]:
			return 6
		elif set[1] and set[2] and set[3] and not set[4] and not set[5] and not set[6] and not set[7]:
			return 7
		elif set[1] and set[2] and set[3] and set[4] and set[5] and set[6] and set[7]:
			return 8
		elif set[1] and set[2] and set[3] and set[4] and not set[5] and set[6] and set[7]:
			return 9
		elif set[1] and set[2] and set[3] and set[4] and set[5] and set[6] and not set[7]:
			return 0
	def getValue(self):
		"""
		Returns the value which will be returned
		"""
		#arrange the digits
		val = self.setToDigit(self.A)
		val = val*10 + self.setToDigit(self.B)
		val = val*10 + self.setToDigit(self.C)
		val = val*10 + self.setToDigit(self.D)

		# set the sign
		if self.sign:
			val = val * -1
		
		# Set up the decimal place
		if self.P[1]:
			val = float(val)/1000
		elif self.P[2]:
			val = float(val)/100
		elif self.P[3]:
			val = float(val)/10
		return val

x = QM1538()
x.read()
print x.getValue()
print x.units
print x.quantity
